﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

namespace SGT_ON
{
    public sealed class Utilidades
    {
        #region Cambiar numeros a letras

        private readonly static string[] _numbersInWords = {

            "uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", "ocho", "nueve",

            "diez", "once", "doce", "trece", "catorce", "quince", "dieciseis", "diecisiete", "dieciocho", "diecinueve",

            "veinte", "veintiuno", "veintidos", "veintitres", "veinticuatro", "veinticinco", "veintiseis", "veintisiete", "veintiocho", "veintinueve",

            "treinta", "cuarenta", "cincuenta", "sesenta", "setenta", "ochenta", "noventa",

                  "ciento", "doscientos", "trescientos", "cuatrocientos", "quinientos", "seiscientos", "setecientos", "ochocientos", "novecientos"

            };



        private const string _centWord = "centavos";

        private const string _oneMillionWord = "un millon";

        private const string _millionsWord = "millones";

        private const string _oneThousandWord = "un mil";

        private const string _thousandWord = "mil";

        private const string _hundredWord = "cien";

        private const string _oneHundredWord = "ciento un";

        private const string _zeroWithWord = "cero con";

        private const string _withWord = "con";

        private const string _andWord = "y";



        /// <summary>

        /// Converts numbers to words

        /// </summary>

        /// <param name="number"></param>

        /// <returns></returns>

        public static string NumberToWords(decimal number)
        {



            if (number > 999999999)
            {

                return "Numero demasiado grande";

            }



            StringBuilder Words;

            string FormattedNumberString;

            int decimalSeparatorLocation;

            int millionsPart;

            int thousandsPart;

            int hundredsPart;

            int decimalsPart;

            int hundreds;

            int tens;

            int units;

            int ActualNumber = 0;



            Words = new StringBuilder();

            FormattedNumberString = number.ToString("000000000.00");

            char DecimalSeparator = Convert.ToChar((Convert.ToString(1.1)).Trim().Substring(1, 1));

            decimalSeparatorLocation = FormattedNumberString.IndexOf(DecimalSeparator);



            millionsPart = Convert.ToInt32(FormattedNumberString.Substring(0, 3));

            thousandsPart = Convert.ToInt32(FormattedNumberString.Substring(3, 3));

            hundredsPart = Convert.ToInt32(FormattedNumberString.Substring(6, 3));

            decimalsPart = Convert.ToInt32(FormattedNumberString.Substring(decimalSeparatorLocation + 1, 2));

            for (int NumberPart = 1; NumberPart <= 4; NumberPart++)
            {

                switch (NumberPart)
                {

                    case 1:
                        {

                            ActualNumber = millionsPart;

                            if (millionsPart == 1)
                            {

                                Words.Append(_oneMillionWord);

                                Words.Append(' ');

                                continue;

                            }

                            break;

                        }

                    case 2:
                        {

                            ActualNumber = thousandsPart;

                            if (millionsPart != 1 && millionsPart != 0)
                            {

                                Words.Append(_millionsWord);

                                Words.Append(' ');

                            }

                            if (thousandsPart == 1)
                            {

                                Words.Append(_oneThousandWord);

                                Words.Append(' ');

                                continue;

                            }

                            break;

                        }

                    case 3:
                        {

                            ActualNumber = hundredsPart;

                            if (thousandsPart != 1 && thousandsPart != 0)
                            {

                                Words.Append(_thousandWord);

                                Words.Append(' ');

                            }

                            break;

                        }

                    case 4:
                        {

                            ActualNumber = decimalsPart;

                            if (decimalsPart != 0)
                            {

                                if (millionsPart == 0 && thousandsPart == 0 && hundredsPart == 0)
                                {

                                    Words.Append(_zeroWithWord);

                                    Words.Append(' ');

                                }

                                else
                                {

                                    Words.Append(_withWord);

                                    Words.Append(' ');

                                }

                            }

                            break;

                        }

                }



                hundreds = (int)(ActualNumber / 100);

                tens = (int)(ActualNumber - hundreds * 100) / 10;

                units = (int)(ActualNumber - (hundreds * 100 + tens * 10));

                if (ActualNumber == 0) continue;



                if (ActualNumber == 100)
                {

                    Words.Append(_hundredWord);

                    Words.Append(' ');

                    continue;

                }

                else
                {

                    if (ActualNumber == 101 && NumberPart != 3)
                    {

                        Words.Append(_oneHundredWord);

                        Words.Append(' ');

                        continue;

                    }

                    else
                    {

                        if (ActualNumber > 100)
                        {

                            Words.Append(_numbersInWords[hundreds + 35]);

                            Words.Append(' ');

                        }

                    }

                }

                if (tens < 3 && tens != 0)
                {

                    Words.Append(_numbersInWords[tens * 10 + units - 1]);

                    Words.Append(' ');

                }

                else
                {

                    if (tens > 2)
                    {

                        Words.Append(_numbersInWords[tens + 26]);

                        Words.Append(' ');

                        if (units == 0)
                        {

                            continue;

                        }

                        Words.Append(_andWord);

                        Words.Append(' ');

                        Words.Append(_numbersInWords[units - 1]);

                        Words.Append(' ');

                    }

                    else
                    {

                        if (tens == 0 && units != 0)
                        {

                            Words.Append(_numbersInWords[units - 1]);

                            Words.Append(' ');

                        }

                    }

                }

            } // end for



            if (decimalsPart != 0)
            {

                Words.Append(_centWord);

            }



            // Resolve particular problems here.

            Words.Replace("uno mil", "un mil");



            return Words.ToString().Trim();

        }





        #endregion

        #region Poner la primer letra de las palabras en mayusculas
        public static string ConvertFirstLetterToUpper(string strWord)
        {
            if ((strWord == null)
                || (strWord == ""))
                return "";

            try
            {
                string[] arrWords = strWord.Split(' ');
                string strTemp2 = string.Empty;

                if (arrWords.Length > 1) //Existe mas de una palabra, Ej ANA MARIA
                {
                    foreach (string strTemp in arrWords)
                    {
                        strTemp2 += strTemp.Substring(0, 1).ToUpper() + strTemp.Substring(1) + " ";
                    }
                }
                else
                    strTemp2 = arrWords[0].Substring(0, 1).ToUpper() + arrWords[0].Substring(1) + " ";

                return strTemp2.Substring(0, strTemp2.Length - 1);
            }
            catch (Exception ex)
            {
                string strError = ex.Message;
                return strWord;
            }
        }
        #endregion

        /// <summary>
        /// Convierte un valor a decimal teniendo en cuenta los . y , para que todo sea tomado con ,
        /// </summary>
        /// <param name="pValor"></param>
        /// <returns></returns>
        public static decimal ConvertirADecimal(string pValor)
        {
            if ((pValor == null)
                || (pValor == ""))
                return Decimal.Zero;

            //si tiene punto y coma, saco el punto
            if (pValor.Contains(".") == true)
            {
                if (pValor.Contains(",") == true)
                    pValor = pValor.Replace(".", "");
                pValor = pValor.Replace(".", ",");
            }

            decimal _resultado;
            decimal.TryParse(pValor, out _resultado);
            return _resultado;
        }

    }

    #region Algoritmo de encriptación
    public class Encriptacion
    {
        public string Clave = "secreta";
        public static string EncryptString(string Message, string Passphrase)
        {
            byte[] Results;
            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();

            // Step 1. We hash the passphrase using MD5
            // We use the MD5 hash generator as the result is a 128 bit byte array
            // which is a valid length for the TripleDES encoder we use below

            MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
            byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));

            // Step 2. Create a new TripleDESCryptoServiceProvider object
            TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();

            // Step 3. Setup the encoder
            TDESAlgorithm.Key = TDESKey;
            TDESAlgorithm.Mode = CipherMode.ECB;
            TDESAlgorithm.Padding = PaddingMode.PKCS7;

            // Step 4. Convert the input string to a byte[]
            byte[] DataToEncrypt = UTF8.GetBytes(Message);

            // Step 5. Attempt to encrypt the string
            try
            {
                ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
                Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length);
            }
            finally
            {
                // Clear the TripleDes and Hashprovider services of any sensitive information
                TDESAlgorithm.Clear();
                HashProvider.Clear();
            }

            // Step 6. Return the encrypted string as a base64 encoded string
            return Convert.ToBase64String(Results);
        }

        public static string DecryptString(string Message, string Passphrase)
        {
            byte[] Results;
            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();

            // Step 1. We hash the passphrase using MD5
            // We use the MD5 hash generator as the result is a 128 bit byte array
            // which is a valid length for the TripleDES encoder we use below

            MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
            byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));

            // Step 2. Create a new TripleDESCryptoServiceProvider object
            TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();

            // Step 3. Setup the decoder
            TDESAlgorithm.Key = TDESKey;
            TDESAlgorithm.Mode = CipherMode.ECB;
            TDESAlgorithm.Padding = PaddingMode.PKCS7;

            // Step 4. Convert the input string to a byte[]
            byte[] DataToDecrypt = Convert.FromBase64String(Message);

            // Step 5. Attempt to decrypt the string
            try
            {
                ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor();
                Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length);
            }
            finally
            {
                // Clear the TripleDes and Hashprovider services of any sensitive information
                TDESAlgorithm.Clear();
                HashProvider.Clear();
            }

            // Step 6. Return the decrypted string in UTF8 format
            return UTF8.GetString(Results);
        }

        /// <summary>
        /// Ejemplo de uso
        /// </summary>
        /// <param name="args"></param>
        private static void Main(string[] args)
        {
            // The message to encrypt.
            string Msg = "This world is round, not flat, don't believe them!";
            string Password = "secret";

            string EncryptedString = EncryptString(Msg, Password);
            string DecryptedString = DecryptString(EncryptedString, Password);

            Console.WriteLine("Message: {0}", Msg);
            Console.WriteLine("Password: {0}", Password);
            Console.WriteLine("Encrypted string: {0}", EncryptedString);
            Console.WriteLine("Decrypted string: {0}", DecryptedString);
        }
    }
    #endregion
}
